// Copyright (C) 2024 Kumo inc.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <stdexcept>
#include <string>

namespace deneb::deneb_error {

    /// Exception thrown when the value of an invalid key was requested.
    struct KeyNotFound : public std::runtime_error {
        using super = std::runtime_error;

        KeyNotFound() : super("Failed to find key") {
        }

        explicit KeyNotFound(const std::string &key)
                : super("Failed to find key: " + key) {
        }
    };

    /// Exception thrown when the value of an expired key was requested.
    struct KeyExpired : public std::runtime_error {
        using super = std::runtime_error;

        explicit KeyExpired(const std::string &key)
                : super("Key found, but expired: " + key) {
        }

        KeyExpired() : super("Key found, but expired") {
        }
    };

    /// Exception thrown when requesting the front or end key of an empty cache.
    struct EmptyCache : public std::runtime_error {
        using super = std::runtime_error;

        explicit EmptyCache(const std::string &what_was_expected)
                : super("Requested " + what_was_expected + " of empty cache") {
        }
    };

    /// Exception thrown when attempting to convert an invalid unordered iterator to
    /// an ordered iterator.
    struct InvalidIteratorConversion : public std::runtime_error {
        using super = std::runtime_error;

        InvalidIteratorConversion()
                : super("Cannot convert past-the-end unordered to ordered iterator") {
        }
    };

    /// Exception thrown when attempting to erase the past-the-end iterator.
    struct InvalidIterator : public std::runtime_error {
        using super = std::runtime_error;

        InvalidIterator() : super("Past-the-end iterator is invalid here") {
        }
    };

    /// Exception thrown when requesting statistics about an unmonitored key.
    struct UnmonitoredKey : public std::runtime_error {
        using super = std::runtime_error;

        UnmonitoredKey() : super("Requested statistics for unmonitored key") {
        }
    };

    /// Exception thrown when requesting the statistics object of a cache when none
    /// was registered.
    struct NotMonitoring : public std::runtime_error {
        using super = std::runtime_error;

        NotMonitoring() : super("Statistics monitoring not enabled for this cache") {
        }
    };

}  // namespace deneb::deneb_error

